package com.kj.misc.service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.eventbus.AsyncEventBus;
import com.kj.misc.domain.MiscStoreType;
import com.kj.misc.domain.MiscValue;

import lombok.Getter;
import lombok.extern.log4j.Log4j2;

@Component
@Log4j2
public class MiscData {
	
	@Autowired
	private MiscStorage storage;
	
	@Getter
	private AsyncEventBus eventBus = new AsyncEventBus("MiscDataBus", Executors.newSingleThreadExecutor());
	
	private Map<String, MiscValue> data = Maps.newHashMap();
	
	private List<String> supportedKeys = Lists.newLinkedList();
	
	private Splitter keySplitter = Splitter.on(',').trimResults().omitEmptyStrings();
	
	public MiscData() {
	}
	
	public void start() {
	}
	
	public void stop() {
		data.clear();		
	}
	
	public void registerData(String key, MiscStoreType storeType) {
		supportedKeys.add(key);
		storage.registerStore(storeType, key);
	}
	
	public void update(String key, double value) {
		
		if(key == null || !supportedKeys.contains(key)) {
			log.warn("Key is null or not supported, key name is " + key);
			return;
		}
		
		MiscValue newValue = MiscValue.at(value);
		update(key, newValue);
	}
	
	public void update(String key, MiscValue newValue) {
		
		if(key == null || !supportedKeys.contains(key)) {
			log.warn("Key is null or not supported, key name is " + key);
			return;
		}
		
		MiscValue oldValue = data.put(key, newValue);
		
		// fire event
		MiscDataEvent event = MiscDataEvent.builder()
			.key(key)
			.oldValue(oldValue)
			.newValue(newValue)
			.build();

		eventBus.post(event);
		
	}
	
	public Map<String, MiscValue> snapshot() {
		return Maps.newHashMap(data);
	}
	
	public Map<String, MiscValue> valueByKeys(String keys) {
		
		Map<String, MiscValue> clone = Maps.newHashMap();
		try {
			keySplitter.splitToList(keys).stream().forEach(s-> {
				MiscValue value = data.get(s);
				if(value != null) {
					clone.put(s, value);
				}
			});
		} catch(Exception e) {
		}
		return clone;
	}
	
	public MiscValue valueByKey(String key) {
		return data.get(key);
	}
	
}
